//
//  GameScene.m
//  HeroNuts
//
//  Created by Magic on 11-3-31.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "GameScene.h"
#import "HeroNuts.h"
#import "HNActionCache.h"
#import "HNActorInfoCache.h"
#import "HNWalk.h"
#import "HNLogicPosition.h"
#import "HNActor.h"
#import "HNFly.h"
#import "HNAttack.h"
#import "HNBeaten.h"
#import "HNDie.h"
#import "HNActionFlowCenter.h"
#import "HNTurnAround.h"
#import "HNEffectCache.h"

//#define TEST_WALK
//#define TEST_FLY
//#define TEST_ATTACK
//#define TEST_BEATEN
//#define TEST_DIE
//#define TEST_FLOWCENTER
//#define TEST_TURNAROUND

@interface GameScene(GameScenePrivateMethod)

-(void) nextRound;
-(void) nextActor;
-(void) spawnActors;
-(void) loadEffects;
@end


HNActor* Halberdier;
HNActor* Nosferatu;


@implementation GameScene 
@class LogicCenter;
//@synthesize actors = actors_;

#pragma mark GameScene - alloc, init, dealloc and Singleton stuff

static GameScene* gameSceneInstance_ = nil;

+(id) scene
{
	CCScene *scene = [CCScene node];
	GameScene *layer = [GameScene node];
	[scene addChild: layer];
	return scene;
}

+(GameScene*) sharedGameScene 
{
	NSAssert(gameSceneInstance_ != nil, @"GameScene not available!");
	return gameSceneInstance_;
}

-(id) init
{
	if((self = [super init])) 
	{
		gameSceneInstance_ = self;
		
		GroundLayer* groundLayer = [GroundLayer node]; 
		[self addChild:groundLayer z:1 tag:LayerTagGroundLayer];
		
		SpriteLayer* spriteLayer = [SpriteLayer node]; 
		[self addChild:spriteLayer z:2 tag:LayerTagSpriteLayer];
		
		//UILayer* uiLayer = [UILayer node]; 
		//[self addChild:uiLayer z:3 tag:LayerTagUILayer]; 
		
        
		EffectLayer* effectLayer = [EffectLayer node]; 
		[self addChild:effectLayer z:4 tag:LayerTagEffectLayer]; 
        
        actors_ = [[NSMutableArray alloc] initWithCapacity:20];
        
		[self spawnActors];
		[self loadEffects];
		
	}
	return self;
}

- (void)loadEffects
{
	[[HNEffectCache sharedEffectCache] addEffectWithFile:@"DrainBlood.plist"];
	[[HNEffectCache sharedEffectCache] addEffectWithFile:@"age.plist"];
}

- (void)spawnActor:(NSString*)name count:(int)count position:(CGPoint)position faceRight:(BOOL)faceRight
{
	[[HNActionCache sharedActionCache] addActionWithFile:[NSString stringWithFormat:@"%@.plist",name]];
	[[HNActorInfoCache sharedActorInfoCache] addActorInfoWithFile:[NSString stringWithFormat:@"%@.json",name]];
	
	HNActor* newActor = [[HNActorFactory sharedActorFactory] newActorWithClassName:name];
	newActor.name = name;
	
	CCSprite* actor_sprite = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"%@-02-00.png",name]];
	newActor.sprite = actor_sprite;
	
	newActor.hexSize = 1;//!!!!!!!!!!!!!!!

	newActor.count = count;    
	newActor.position = position;
	[[HNGroundLogic sharedGroundLogic] addActor:newActor inPosition:position];
	
	CGPoint originalPosition = [[HNActorInfoCache sharedActorInfoCache] originalPositionByActor:name];
    CGPoint distance = [HNLogicPosition distanceInPixelsFrom:ccp(0,0) to:position];
	CGPoint spritePosition = ccp(originalPosition.x+distance.x,originalPosition.y+distance.y);
		
	newActor.sprite.anchorPoint = ccp(0,1);	
	newActor.sprite.position = spritePosition;
    newActor.faceRight = faceRight;
    newActor.leftSide = faceRight;
	
	[self.spriteLayer addChild:newActor.sprite];
    [actors_ addObject:newActor];
	[newActor release];
}

-(void) spawnActors
{
    //矮油我去！！
    //生成sprite的时候要先赋name再赋sprite
    //以后交给霍巨赋name就好了
    
    //cursor resource 
	[[HNActionCache sharedActionCache] addActionWithFile:@"Cursor.plist"];
	[[HNActorInfoCache sharedActorInfoCache] addActorInfoWithFile:@"Cursor.json"];

	//Halberdier resource
//	[[HNActionCache sharedActionCache] addActionWithFile:@"Halberdier.plist"];
//	[[HNActorInfoCache sharedActorInfoCache] addActorInfoWithFile:@"Halberdier.json"];
    
    //Nosferatu resource
 //   [[HNActionCache sharedActionCache] addActionWithFile:@"Nosferatu.plist"];
//	[[HNActorInfoCache sharedActorInfoCache] addActorInfoWithFile:@"Nosferatu.json"];
	
    
	[self spawnActor:@"Halberdier" count:30 position:ccp(0,2) faceRight:YES];
    [self spawnActor:@"Nosferatu" count:9 position:ccp(14,9) faceRight:NO];
	[self spawnActor:@"PowerLich" count:2 position:ccp(14,6) faceRight:NO];
    [self spawnActor:@"Zealot" count:4 position:ccp(0,6) faceRight:YES];
    [self spawnActor:@"SkeletonWarrior" count:4 position:ccp(14,2) faceRight:NO];
    [self spawnActor:@"Crusader" count:4 position:ccp(0,9) faceRight:YES];
    
	/*//spawn a Halberdier
	Halberdier = [[HNActorFactory sharedActorFactory] newActorWithClassName:@"Halberdier"];
	CCSprite* Halberdier_sprite = [CCSprite spriteWithSpriteFrameName:@"Halberdier-02-00.png"];
	
	Halberdier.name = @"Halberdier";  
    Halberdier.count = 9;
    Halberdier.sprite = Halberdier_sprite;
	Halberdier.position = ccp(5,3);
	[[HNGroundLogic sharedGroundLogic] addActor:Halberdier inPosition:Halberdier.position];
	//NSDictionary* actor_info = [[HNActorInfoCache sharedActorInfoCache] actorInfoByName:@"Halberdier"];
	CGPoint originalPosition = [[HNActorInfoCache sharedActorInfoCache] originalPositionByActor:@"Halberdier"];
    CGPoint distance = [HNLogicPosition distanceInPixelsFrom:ccp(0,0) to:Halberdier.position];
	CGPoint spritePosition = ccp(originalPosition.x+distance.x,originalPosition.y+distance.y);
    
	Halberdier.sprite.anchorPoint = ccp(0,1);	
	Halberdier.sprite.position = spritePosition;
    Halberdier.faceRight = YES;
    Halberdier.leftSide = YES;
  //Halberdier.canFly = YES;
	[self.spriteLayer addChild:Halberdier.sprite z:1 tag:2];
    [actors_ addObject:Halberdier];
    
    //spawn a Nosferatu 
	Nosferatu = [[HNActorFactory sharedActorFactory] newActorWithClassName:@"Halberdier"];
	CCSprite* Nosferatu_sprite = [CCSprite spriteWithSpriteFrameName:@"Nosferatu-02-00.png"];
	
	Nosferatu.name = @"Nosferatu";
    Nosferatu.count = 19;
    Nosferatu.sprite = Nosferatu_sprite;
	Nosferatu.position = ccp(3,2); 
    Nosferatu.canFly = YES;
    [[HNGroundLogic sharedGroundLogic] addActor:Nosferatu inPosition:Nosferatu.position];
	
    CGPoint originalPosition = [[HNActorInfoCache sharedActorInfoCache] originalPositionByActor:@"Nosferatu"];
	CGPoint distance = [HNLogicPosition distanceInPixelsFrom:ccp(0,0) to:Nosferatu.position];
    CGPoint spritePosition = ccp(originalPosition.x+distance.x,originalPosition.y+distance.y);
    
	Nosferatu.sprite.anchorPoint = ccp(0,1);	
	Nosferatu.sprite.position = spritePosition;
    Nosferatu.faceRight = YES;
    Nosferatu.leftSide = YES;
	[self.spriteLayer addChild:Nosferatu.sprite z:1 tag:2];
  
  [actors_ addObject:Nosferatu];
    */
    //------------------------------------------------------------------------------ that's what your want----------
  //  id a = [[NSClassFromString(@"LogicCenter") alloc] init];
  //  [a actorA:Halberdier attackActorB:Nosferatu];
  //  NSMutableArray* nsa = [a getActionQueue];
    //--------------------------------------------------that's all---------------------------
}

-(GroundLayer*) groundLayer
{
	CCNode* layer = [self getChildByTag:LayerTagGroundLayer];	
	return (GroundLayer*)layer;
}

-(SpriteLayer*) spriteLayer
{
	CCNode* layer = [self getChildByTag:LayerTagSpriteLayer];
	return (SpriteLayer*)layer;
}

-(UILayer*) uiLayer
{
	CCNode* layer = [self getChildByTag:LayerTagUILayer];
	return (UILayer*)layer;
}

-(EffectLayer*) effectLayer
{
	CCNode* layer = [self getChildByTag:LayerTagEffectLayer];
	return (EffectLayer*)layer;
}


-(HNActor*) currentActor
{
    return (HNActor*)[actors_ objectAtIndex:currentActorIndex_];
}

- (void) dealloc
{
    [Halberdier release];
    [Nosferatu release];
    /////////////////////////////////////
    
    [actors_ release];
	gameSceneInstance_ = nil;
	[super dealloc];
}


#pragma mark GameScene - Scene Logic 

-(void) onEnterTransitionDidFinish
{
	//[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"battle_background_4.mp3"];
	
	[self nextRound];

    
   // id b = [[HNActorFactory sharedActorFactory] newActorWithClassName:@"RoyalGriffin"];
    
   //[[[NSClassFromString(@"LogicCenter") alloc] init] actorA:a attackActorB:b];
/* 
#ifdef TEST_FLOWCENTER
    HNLogicPosition *des = [[HNLogicPosition alloc] initWithPoint:ccp(2,2)];
    [[HNActionFlowCenter sharedActionFlowCenter] currentActorMoveTo:des attack:nil];
    [des release];
#endif
    
#ifdef TEST_WALK	
    HNLogicPosition* p1 = [[HNLogicPosition alloc] initWithPoint:ccp(0,3)];
    HNLogicPosition* p2 = [[HNLogicPosition alloc] initWithPoint:ccp(1,3)];
    HNLogicPosition* p3 = [[HNLogicPosition alloc] initWithPoint:ccp(2,3)];
    HNLogicPosition* p4 = [[HNLogicPosition alloc] initWithPoint:ccp(3,3)];
    HNLogicPosition* p5 = [[HNLogicPosition alloc] initWithPoint:ccp(2,2)];
	
	NSMutableArray* path = [NSMutableArray arrayWithObjects:p1,p2,p3,p4,p5,nil];
    
    HNWalk* walk = [[HNWalk alloc] initWithActorName:@"Halberdier" walkPath:path faceRight:Halberdier.faceRight];
	[walk startWithTarget:Halberdier];
    [walk release];
#endif
    
 
#ifdef TEST_FLY    
    HNFly *fly = [[HNFly alloc] initWithActorName:@"Nosferatu" from:Nosferatu.position to:ccp(0,6) faceRight:YES];
    [fly startWithTarget:Nosferatu];
    [fly release];
#endif
   
#ifdef TEST_ATTACK
    HNAttack *attack = [[HNAttack alloc] initWithActorName:@"Halberdier" direction:@"FRONT"];
    [attack startWithTarget:Halberdier]; 
    [attack release];
#endif
    
#ifdef TEST_BEATEN
    HNBeaten *beaten  = [[HNBeaten alloc] initWithActorName:@"Nosferatu"];
    [beaten startWithTarget:Nosferatu];
    [beaten release];
#endif
    
#ifdef TEST_DIE
    HNDie *die = [[HNDie alloc] initWithActorName:@"Nosferatu"];
    [die startWithTarget:Nosferatu];
    [die release];
#endif
    
#ifdef TEST_TURNAROUND
    HNTurnAround *turnAround = [[HNTurnAround alloc] initWithActorName:@"Halberdier" nowFaceRight:YES];
    [turnAround startWithTarget:Halberdier];
    [turnAround release];
#endif
    
    */
}

-(void) nextRound
{
	currentActorIndex_ = -1;
	
	//sort actors by speed
	//actors_ = [actors_ sortedArrayUsingSelector:@selector(actorSpeedCompare:)];
	
	[self nextActor];
}

-(void) nextActor
{
	currentActorIndex_++;
	
	if (currentActorIndex_ < [actors_ count]) 
	{
		[self.groundLayer prepareForNextActor:self.currentActor];
	}
	else 
	{
		[self nextRound];
	}


	
	
}

@end
